/**************************************************************************************
*
*	Copyright (C) 2009 - 2012 Brent Andrew O. Chua - See LICENSE.txt for more info.
*		
*	Filename	-	XMLDocument.cpp
*
*	Comments	-	See XMLDocument.h
*
**************************************************************************************/
#include "../Include/XMLDocument.h"
#include "../Include/XMLElement.h"
#include "../Include/String.h"
#include "../Include/FileSystem.h"
#include "../Include/Engine.h"
#include "../Include/ResourceCache.h"

namespace Pulse
{
	XMLDocument::XMLDocument( void )
	{
		m_bManageDoc = TRUE; 
		m_pDoc = new tinyxml2::XMLDocument; 
	}

	XMLDocument::~XMLDocument( void )
	{
		if ( m_bManageDoc )
			PSX_SafeDelete( m_pDoc );
	}

	XMLDocument::XMLDocument( const CHAR *pFilename )
	{
		//Load xml file
		FileHandlePtr hFile = FileSystem::GetInstance()->OpenFile( pFilename );
		if ( !hFile )
		{
			PSX_PushError( "Failed to load file %s.", pFilename );
		}

		ResHandlePtr hResource =  Engine::GetInstance()->GetResourceCache()->GetHandle( hFile );

		m_pDoc = new tinyxml2::XMLDocument;
		m_pDoc->Parse( (const char*)hResource->GetBuffer(), (unsigned int)hResource->GetSize() );

		if ( m_pDoc->Error() )
		{
			m_pDoc->GetErrorStr1();
			PSX_PushWarning( "Failed to load xml file %s. %s.", pFilename, m_pDoc->GetErrorStr1() );
		}

		m_bManageDoc = TRUE;

	}

	XMLDocument::XMLDocument( tinyxml2::XMLDocument *pDoc )
		: m_bManageDoc( FALSE ), m_pDoc( pDoc )
	{

	}

	BOOL XMLDocument::IsValid( void )
	{
		return !m_pDoc->Error();
	}

	XMLElementPtr XMLDocument::GetFirstChild( void )
	{
		tinyxml2::XMLElement *pELem = m_pDoc->FirstChildElement();

		if ( pELem )
			return new XMLElement( this, pELem);
		else
			return PSX_NULL;
	}

	XMLElementPtr XMLDocument::GetLastChild( void )
	{
		tinyxml2::XMLElement *pELem = m_pDoc->LastChildElement();

		if ( pELem )
			return new XMLElement( this, pELem);
		else
			return PSX_NULL;
	}

	XMLElementPtr XMLDocument::FindChild( const CHAR *pName )
	{
		Char buffer[250];
		String::ToMultiByte( pName, buffer, 250 );

		return new XMLElement( this, m_pDoc->FirstChildElement(buffer) );
	}

	XMLElementPtr XMLDocument::CreateElement( const CHAR *pName )
	{
		Char buffer[250];
		String::ToMultiByte( pName, buffer, 250 );

		return new XMLElement( this, m_pDoc->NewElement( buffer ) );
	}

	XMLElementPtr XMLDocument::CreateChild( const CHAR *pName )
	{
		Char buffer[250];
		String::ToMultiByte( pName, buffer, 250 );
		tinyxml2::XMLElement *pElem = m_pDoc->NewElement( buffer );
		AddChild( pElem );
		return new XMLElement( this, pElem );
	}

	void XMLDocument::ClearChildren( void )
	{
		m_pDoc->DeleteChildren();
	}

	EErrorCode::Type XMLDocument::SaveFile( const CHAR *pFilename )
	{
		Char buffer[250];
		String::ToMultiByte( pFilename, buffer, 250 );

		//FILE file;
		m_pDoc->SaveFile(  buffer );

		int x = 0;

		return EErrorCode::OKAY;
	}

	void XMLDocument::AddChild( tinyxml2::XMLElement *pElem )
	{
		m_pDoc->InsertEndChild( pElem );
	}

}